package com.reactim.message.repository;

import com.reactim.message.entity.Message;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.repository.Query;
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
import org.springframework.stereotype.Repository;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.time.LocalDateTime;

/**
 * 消息数据访问接口
 */
@Repository
public interface MessageRepository extends ReactiveMongoRepository<Message, String> {
    
    /**
     * 根据消息ID查找消息
     */
    Mono<Message> findByMessageId(String messageId);
    
    /**
     * 根据会话ID查找消息（分页）
     */
    Flux<Message> findByConversationIdOrderByCreatedAtDesc(String conversationId, Pageable pageable);
    
    /**
     * 根据发送者和接收者查找私聊消息
     */
    @Query("{'$or': [{'fromUserId': ?0, 'toUserId': ?1}, {'fromUserId': ?1, 'toUserId': ?0}], 'status': 'NORMAL'}")
    Flux<Message> findPrivateMessages(Long userId1, Long userId2, Pageable pageable);
    
    /**
     * 根据群组ID查找群聊消息
     */
    Flux<Message> findByGroupIdAndStatusOrderByCreatedAtDesc(Long groupId, Message.MessageStatus status, Pageable pageable);
    
    /**
     * 根据用户ID查找相关消息
     */
    @Query("{'$or': [{'fromUserId': ?0}, {'toUserId': ?0}, {'groupId': {'$in': ?1}}], 'status': 'NORMAL'}")
    Flux<Message> findUserRelatedMessages(Long userId, java.util.List<Long> groupIds, Pageable pageable);
    
    /**
     * 根据时间范围查找消息
     */
    Flux<Message> findByCreatedAtBetweenOrderByCreatedAtDesc(LocalDateTime startTime, LocalDateTime endTime, Pageable pageable);
    
    /**
     * 统计会话消息数量
     */
    Mono<Long> countByConversationIdAndStatus(String conversationId, Message.MessageStatus status);
    
    /**
     * 统计用户未读消息数量
     */
    @Query(value = "{'toUserId': ?0, 'status': 'NORMAL'}", count = true)
    Mono<Long> countUnreadMessages(Long userId);
    
    /**
     * 查找指定时间之后的消息
     */
    Flux<Message> findByConversationIdAndCreatedAtAfterOrderByCreatedAtAsc(String conversationId, LocalDateTime afterTime);
    
    /**
     * 根据序号查找消息
     */
    Flux<Message> findByConversationIdAndSequenceGreaterThanOrderBySequenceAsc(String conversationId, Long sequence);
    
    /**
     * 删除指定时间之前的消息（物理删除）
     */
    Mono<Void> deleteByCreatedAtBefore(LocalDateTime beforeTime);
    
    /**
     * 查找需要撤回的消息
     */
    @Query("{'messageId': ?0, 'fromUserId': ?1, 'status': 'NORMAL'}")
    Mono<Message> findRecallableMessage(String messageId, Long fromUserId);
    
    /**
     * 全文搜索消息
     */
    @Query("{'$text': {'$search': ?0}, 'status': 'NORMAL'}")
    Flux<Message> searchMessages(String keyword, Pageable pageable);
}